/*
 * =====================================================================================
 *
 *       Filename:  main.c
 *
 *    Description:
 *
 *        Version:  1.0
 *        Created:  2015-6-8 15:10:48
 *       Revision:  none
 *       Compiler:  WinARM
 *
 *         Author:  FengJie<fengjie@toecsec.com>
 *        Company:  TOEC Security
 *
 * =====================================================================================
 */
// NutOS Headers
#include <arch/arm.h>
#include <dev/board.h>
#include <sys/version.h>
#include <sys/confnet.h>
#include <sys/timer.h>
#include <arpa/inet.h>
#include <net/route.h>
#include <pro/dhcp.h>

// Standard C Headers
#include <stdio.h>
#include <string.h>
#include <io.h>

// User Define Headers
#include "AT91SAM7X256.h"
#include "board_config.h"
#include "telnet_thread.h"
#include "utils.h"
#include "version.h"

/*
 * To save RAM, we store large strings in program space. With AVRGCC we
 * would be able to use the PSTR() macro and put the text directly in
 * the statement that uses it. But ICCAVR doesn't support anything like
 * this. Sigh.
 */
prog_char vbanner_P[] = "\n\n********************************************\n"
                        "TOECSEC " PROJ_DESC " Based on Nut/OS %s\n"
                        "Compliler: " CC_STRING "\n"
                        "Firmware version: " FM_VER "\n"
                        "********************************************\n";

int main(void)
{
    u_long baud = 115200;
    u_char mac[6] = { 0x00, 0x06, 0x98, 0x00, 0x00, 0x55 };
    u_long timeout = 500;

    /*
     * Register all devices used in our application.
     */
    NutRegisterDevice(&DEV_DEBUG, 0, 0);
    NutRegisterDevice(&DEV_ETHER, 0x8300, 5);

    /*
     * Assign stdout to the UART device.
     */
    freopen(DEV_DEBUG_NAME, "w", stdout);
    _ioctl(_fileno(stdout), UART_SETSPEED, &baud);
    _ioctl(_fileno(stdout), UART_SETREADTIMEOUT, &timeout);
    printf_P(vbanner_P, NutVersionString());
#ifdef NUTDEBUG
    NutTraceTcp(stdout, 1);
    NutTraceOs(stdout, 0);
    NutTraceHeap(stdout, 0);
    NutTracePPP(stdout, 0);
#endif

    NutNetLoadConfig(DEV_ETHER_NAME);
    memcpy(confnet.cdn_mac, mac, 6);
    NutNetSaveConfig();

    /*
     * Setup the ethernet device. Try DHCP first. If this is
     * the first time boot with empty EEPROM and no DHCP server
     * was found, use hardcoded values.
     */
    //printf("This is new firmware\r\n");
    printf("Configure eth0...");
    if (NutDhcpIfConfig("eth0", 0, 60000)) {
        printf("initial boot...");
        if (NutDhcpIfConfig("eth0", mac, 60000)) {
            u_long ip_addr = inet_addr("192.168.1.249");
            u_long ip_mask = inet_addr("255.255.255.0");

            printf("no DHCP...");
            NutNetIfConfig("eth0", mac, ip_addr, ip_mask);
            /* If not in a local network, we must also call
               NutIpRouteAdd() to configure the routing. */
        }
    }
    puts("OK");
    printf("IP: %s\n", inet_ntoa(confnet.cdn_ip_addr));

    REG32(PIOA_PER) |= AT91C_PIO_PA20;
    REG32(PIOA_OER) |= AT91C_PIO_PA20;
    REG32(PIOA_OWER) |= AT91C_PIO_PA20;
    REG32(PIOA_PUDR) |= AT91C_PIO_PA20;

    NutThreadSetPriority(110);
    telnet_thread_create();

    while (1) {
        AT91_WATCHDOG_RESTART;
        REG32(PIOA_CODR) |= AT91C_PIO_PA20;
        NutSleep(1000);
        REG32(PIOA_SODR) |= AT91C_PIO_PA20;
        NutSleep(1000);
    }

    return 0;
}
